using System;
using System.Collections;
using Cysharp.Threading.Tasks;
using UnityEngine;
using YooAsset;

namespace YooAssetsSystem.Patch
{
	/// <summary>
	/// 初始化更新/资源包 1
	/// </summary>
	public class PatchInitNode : BasePatchNode
	{
		public override void OnEnter()
		{
			Owner.Event.ChangeStateEvent?.Invoke($"初始化资源包");

			UniTask.ToCoroutine(async () =>
			{
				var playMode = Owner?.Config.playMode ?? EPlayMode.EditorSimulateMode;
				shareData.package = Owner.Package;
				Debug.Log($"准备 创建资源包 -- {Owner.Package}");
				var package = YooAssets.TryGetPackage(shareData.package);
				if (package == null)
				{
					Debug.Log($"创建资源包 -- {Owner.Package}");
					package = YooAssets.CreatePackage(shareData.package);
				}

				if (Owner.Config.isDefaultPackage)
				{
					YooAssets.SetDefaultPackage(package);
				}

				if (package.InitializeStatus != EOperationStatus.Succeed)
				{
					InitializationOperation operation = null;

					switch (playMode)
					{
						case EPlayMode.EditorSimulateMode:
							operation = await IntoMode_Editor(shareData.package, package);
							break;
						case EPlayMode.OfflinePlayMode:
							operation = await IntoMode_Offline(package);
							break;
						case EPlayMode.HostPlayMode:
							operation = await IntoMode_HostPlayMode(package);
							break;
						case EPlayMode.WebPlayMode:
							operation = await IntoMode_WebPlayMode(package);
							break;
						default:
						{
							throw new Exception($"未匹配的热更模式 -- {playMode}");
							break;
						}
					}

					// 如果初始化失败弹出提示界面
					if (operation == null || operation.Status != EOperationStatus.Succeed)
					{
						Debug.LogError($"{operation.Error}");
						Owner.Event.UpdateFailedEvent?.Invoke($"{GetType().Name}失败, 停止更新");
					}
					else
					{
						machine.ChangeState<UpdateVersionNode>();
					}
				}
				else
				{
					machine.ChangeState<UpdateVersionNode>();
				}
				
			});
		}

		protected async UniTask<InitializationOperation> IntoMode_Editor(string packageName, ResourcePackage package)
		{
			InitializationOperation operation = null;
			var buildResult = EditorSimulateModeHelper.SimulateBuild(packageName);
			var packageRoot = buildResult.PackageRootDirectory;
			var createParameters = new EditorSimulateModeParameters();
			createParameters.EditorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot);
			operation = package.InitializeAsync(createParameters);
			
			await operation.ToUniTask();
			
			return operation;
		}

		protected async UniTask<InitializationOperation> IntoMode_Offline(ResourcePackage package)
		{
			InitializationOperation operation = null;
			var createParameters = new OfflinePlayModeParameters();
			createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
			operation = package.InitializeAsync(createParameters);
						
			await operation.ToUniTask();
			
			return operation;
		}

		protected async UniTask<InitializationOperation> IntoMode_HostPlayMode(ResourcePackage package)
		{
			InitializationOperation operation = null;
			string defaultHostServer = Owner.GetHostServerURL();
			string fallbackHostServer = Owner.GetHostServerURL();
			IRemoteServices remoteServices = new PatchSeveice.RemoteServices(defaultHostServer, fallbackHostServer);
			var createParameters = new HostPlayModeParameters();
			createParameters.BuildinFileSystemParameters = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
			createParameters.CacheFileSystemParameters = FileSystemParameters.CreateDefaultCacheFileSystemParameters(remoteServices);
			operation = package.InitializeAsync(createParameters);
						
			await operation.ToUniTask();
			
			return operation;
		}

		protected async UniTask<InitializationOperation> IntoMode_WebPlayMode(ResourcePackage package)
		{
			Debug.LogError($"注意如果微信或抖音需要单独实现，不是请忽略");
			InitializationOperation operation = null;
			string defaultHostServer = Owner.GetHostServerURL();
			string fallbackHostServer = Owner.GetHostServerURL();
			IRemoteServices remoteServices = new PatchSeveice.RemoteServices(defaultHostServer, fallbackHostServer);
			var webServerFileSystemParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
			var webRemoteFileSystemParams = FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(remoteServices); //支持跨域下载
			
			var initParameters = new WebPlayModeParameters();
			initParameters.WebServerFileSystemParameters = webServerFileSystemParams;
			initParameters.WebRemoteFileSystemParameters = webRemoteFileSystemParams;
			
			operation = package.InitializeAsync(initParameters);
			await operation.ToUniTask();
			
			return operation;
		}

		public override void OnExit()
		{
			base.OnExit();
		}

		/// <summary>
		/// 远端资源地址查询服务类
		/// </summary>
		class RemoteService : IRemoteServices
		{
			private readonly string defaultHostServer;
			private readonly string fallbackHostServer;

			public RemoteService(string defaultHostServer, string fallbackHostServer)
			{
				this.defaultHostServer = defaultHostServer;
				this.fallbackHostServer = fallbackHostServer;
			}

			string IRemoteServices.GetRemoteMainURL(string fileName)
			{
				return $"{defaultHostServer}/{fileName}";
			}

			string IRemoteServices.GetRemoteFallbackURL(string fileName)
			{
				return $"{fallbackHostServer}/{fileName}";
			}
		}
	}
}
